package com.financing.wap.web.controller.api;



import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.financing.wap.util.*;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJacksonJsonView;

import com.financing.wap.common.ResultMap;
import com.financing.wap.common.ResultMap.STATUS;
import com.financing.wap.dto.FileType;
import com.financing.wap.web.controller.BaseController;

@Controller("fileUploadController")
@RequestMapping("/api")
public class FileUploadController  extends BaseController  implements HandlerExceptionResolver{

	private String fileBaseDir;
	
	private Map<String,String> fileDir = new HashMap<String,String>();
	
	private List<String> allowList;
	
	Logger logger = Logger.getLogger(getClass());

	private String aliyunOss = PropertiesUtils.getValue("AliyunOss");

	@RequestMapping("/fileUpload")
	@ResponseBody
	public ResultMap fileUpload(HttpServletRequest request, HttpServletResponse response){
		logger.info("in file upload");
		ResultMap result = new ResultMap();
		String filePath = getFilePath(request);
		if(StringUtil.isNullOrEmptyStr(filePath)){
			log.warn("file type not exist!");
			result.setStatus(STATUS.ERROR);
			result.setStatusCode(ResultMap.STATUS_CODE_SAVE_FILE_DIR_ERROR);
			return result;
		}

		try{
			CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
			if(multipartResolver.isMultipart(request))
	        {
				logger.info("in file upload  isMultipart");
	            //将request变成多部分request
	            MultipartHttpServletRequest multiRequest=(MultipartHttpServletRequest)request;
	           //获取multiRequest 中所有的文件名
	            Map<String,MultipartFile> mutipartFileMap = multiRequest.getFileMap();

	            Iterator<Entry<String, MultipartFile>> mutipartFileIterator =  mutipartFileMap.entrySet().iterator();
	            while(mutipartFileIterator.hasNext())
	            {
					logger.info("in file upload  mutipartFileIterator");
	            	Entry<String, MultipartFile> entry = mutipartFileIterator.next();
	                MultipartFile file=entry.getValue();

	                String suffix = file.getOriginalFilename().substring(
	                        file.getOriginalFilename().lastIndexOf("."));
	                    if(null != suffix && suffix.length() > 1){
	                        suffix = suffix.substring(1);
	                    }
	                    log.info("upload file type ! suffix type is "+suffix);
	                    //判断文件后缀是否在允许的范围内
	                    if(suffix == null || !isAllowFileType(suffix.toLowerCase())){
	                        result.setStatus(STATUS.ERROR);
	                        result.setStatusCode(ResultMap.STATUS_CODE_FILE_TYPE_ERROR);
	                        getJsonData(request,response,result);
	                        return null;
	                    }


	                FileType fileType = FileTypeJudge.getType(file.getBytes());

                	log.info("upload file type ! file type is "+fileType);

	                if(fileType==null||!isAllowFileType(fileType.toString())){
	                	result.setStatus(STATUS.ERROR);
	    	        	result.setStatusCode(ResultMap.STATUS_CODE_FILE_TYPE_ERROR);
	    	        	getJsonData(request,response,result);
	    				return null;
	                }

	                if(file!=null && (!file.isEmpty()) &&  entry.getKey() !=null && entry.getKey().length()>0)
	                {
	                	StringBuffer fileFullPath = new StringBuffer();
	                	fileFullPath.append(fileBaseDir)
	                				.append(filePath)
	                				.append("/")
	                				.append(DateUtil.getDate())
	                				.append("/")
	                				.append(System.currentTimeMillis())
									.append(file.getOriginalFilename().replaceAll(" ", ""));



						//判断 是否-oss
						logger.info("fileUpload.shtml  AliyunOss:"+aliyunOss);
						if(!"true".equals(aliyunOss)) {
							File dir = new File(fileFullPath.toString());
							if(!dir.exists()){
								dir.mkdirs();
							}
							//上传
							File fileTmp = new File(fileFullPath.toString());

							if(!fileTmp.exists()){
								fileTmp.createNewFile();
								log.info("create new file !");
							}
							file.transferTo(fileTmp);
						}else{
							AliyunOssUtil.writeFile(file.getInputStream(), StringUtils.replace(fileFullPath.toString(),fileBaseDir+"/",""));
						}

	        			result.setStatus(STATUS.SUCCESS);
	        			result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
	        			result.setAttribute("fileUrl", fileFullPath.toString().substring(fileBaseDir.length()));
						logger.info("in file upload  fileUrl:"+fileFullPath.toString().substring(fileBaseDir.length()));
	        			return result;
	                }

	            }

	        }
		}catch(Exception e){
			log.error("upload file error:",e);
			result.setStatus(STATUS.ERROR);
			result.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
			return result;
		}

		log.warn("no file upload!");
		result.setStatus(STATUS.ERROR);
		result.setStatusCode(ResultMap.STATUS_CODE_NO_FILE_UPLOAD);
		return result;

	}

	@RequestMapping("/fileUploadUeditor")
	public ResultMap fileUploadUeditor(HttpServletRequest request, HttpServletResponse response){
		logger.info("in file upload");
		ResultMap result = new ResultMap();
		String filePath = getFilePath(request);
		if(StringUtil.isNullOrEmptyStr(filePath)){
			log.warn("file type not exist!");
			result.setStatus(STATUS.ERROR);
			result.setStatusCode(ResultMap.STATUS_CODE_SAVE_FILE_DIR_ERROR);
			getJsonData(request,response,result);
			return null;
		}
		try{
			CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
			if(multipartResolver.isMultipart(request))
	        {
	            //将request变成多部分request
	            MultipartHttpServletRequest multiRequest=(MultipartHttpServletRequest)request;
	           //获取multiRequest 中所有的文件名
	            Map<String,MultipartFile> mutipartFileMap = multiRequest.getFileMap();
	             
	            Iterator<Entry<String, MultipartFile>> mutipartFileIterator =  mutipartFileMap.entrySet().iterator();
	            while(mutipartFileIterator.hasNext())
	            {
	            	Entry<String, MultipartFile> entry = mutipartFileIterator.next();
	                MultipartFile file=entry.getValue();
	                
	                FileType fileType = FileTypeJudge.getType(file.getBytes());
	                
                	log.info("upload file type ! file type is "+fileType);
                	
	                if(!isAllowFileType(fileType.toString())){
	                	result.setStatus(STATUS.ERROR);
	    	        	result.setStatusCode(ResultMap.STATUS_CODE_FILE_TYPE_ERROR);
	    	        	getJsonData(request,response,result);
	    				return null;
	                }
	                if(file!=null && (!file.isEmpty()) &&  entry.getKey() !=null && entry.getKey().length()>0)
	                {
	                	StringBuffer fileFullPath = new StringBuffer();
	                	fileFullPath.append(fileBaseDir)
	                				.append(filePath)
	                				.append("/")
	                				.append(DateUtil.getDate())
	                				.append("/")
	                				.append(System.currentTimeMillis())
									.append(file.getOriginalFilename().replaceAll(" ", ""));


						//判断 是否-oss
						logger.info("fileUpload.shtml  AliyunOss:"+aliyunOss);
						if(!"true".equals(aliyunOss)) {
							File dir = new File(fileFullPath.toString());
							if(!dir.exists()){
								dir.mkdirs();
							}
							//上传
							File fileTmp = new File(fileFullPath.toString());

							if(!fileTmp.exists()){
								fileTmp.createNewFile();
								log.info("create new file !");
							}
							file.transferTo(fileTmp);
						}else{
							AliyunOssUtil.writeFile(file.getInputStream(), StringUtils.replace(fileFullPath.toString(),fileBaseDir+"/",""));
						}
	        			
	        			result.setStatus(STATUS.SUCCESS);
	        			result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
	        			result.setAttribute("fileUrl", fileFullPath.toString().substring(fileBaseDir.length()));
	        			getJsonData(request,response,result);
	        			return null;
	                }
	            }
	        }
		}catch(Exception e){
			log.error("upload file error:",e);
			result.setStatus(STATUS.ERROR);
			result.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
			getJsonData(request,response,result);
			return null;
		}
		
		log.warn("no file upload!");
		result.setStatus(STATUS.ERROR);
		result.setStatusCode(ResultMap.STATUS_CODE_NO_FILE_UPLOAD);
		getJsonData(request,response,result);
		return null;
		
	}
	private void getJsonData(HttpServletRequest request,HttpServletResponse response,Object result)
    {
        String callback = null;
        
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = null;
        
        if(result == null)
        {
            try
            {
                String jsonStr = "";
                out = response.getWriter();
                out.println(jsonStr);
            }
            catch (Exception e)
            {
            }
            finally
            {
                if (null != out)
                {
                    out.close();
                }
            }
        }
        
        try
        {
                
            JSONObject json = JSONObject.fromObject(result);
            String jsonStr = json.toString();
            if(!StringUtil.isNullOrEmptyStr(callback))
            {
                jsonStr =  callback + "("+ jsonStr +")";
            }
            
            
            out = response.getWriter();
            out.print(jsonStr);
        }
        catch (Exception e)
        {
        }
        finally
        {
            if (null != out)
            {
                out.close();
            }
        }
    }
	@Autowired
	private void setDir(){
		//注入文件根目录
		this.fileBaseDir = PropertiesUtils.getValue("fileBaseDir");
		
		// 注入所有可以上传文件的路径
		String fileTypeDir = PropertiesUtils.getValue("fileTypeDir");
		String[] fileTypes = fileTypeDir.split(";");
		for(String tmp : fileTypes){
			String[] tmpTypes = tmp.split(":");
			if(tmpTypes.length==2){
				fileDir.put(tmpTypes[0], tmpTypes[1]);
			}
		}
		
		//注入允许上传的文件类型
		allowList = new ArrayList<String>();
		String[] allowTypes = PropertiesUtils.getValue("fileAllowTypes").split(",");
		for(String type : allowTypes){
			allowList.add(type);
		}
		
	}
	
	/**
	 * 
	 * @Title: getFilePath
	 * @Description: 根据文件类型选择上传文件路径 
	 * @param @param request
	 * @param @return   
	 * @return String   
	 * @throws
	 */
	private String getFilePath(HttpServletRequest request){
		String fileType = request.getParameter("fileType");
		if(StringUtil.isNullOrEmptyStr(fileType)){
			return null;
		}
		return fileDir.get(fileType);
	}
	
	/**
	 * 
	 * @Title: isAllowFileType
	 * @Description: 判断文件类型是否未允许的类型 
	 * @param @param type
	 * @param @return   
	 * @return boolean   
	 * @throws
	 */
	private boolean isAllowFileType(String type){
		return allowList.contains(type.toLowerCase());
	}

	@Override
	@ResponseBody
	public ModelAndView resolveException(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception exception) {
		logger.info("in Upload Exception");
		Map<String,Object> result = new HashMap<String, Object>();
		logger.info(((MaxUploadSizeExceededException)exception).getMaxUploadSize());
        if (exception instanceof MaxUploadSizeExceededException) { 
    		logger.info("in Upload MaxUploadSizeExceededException ");
    		result.put("status",STATUS.FAILE);
            result.put("statusCode","9001");
        } else {
    		result.put("status",STATUS.FAILE);
            result.put("statusCode","9002");
        } 
        result.put("attributes", new HashMap<String, Object>() );
        ModelAndView mav = new ModelAndView(); 
        mav.setView(new MappingJacksonJsonView());
        mav.addAllObjects(result);
        return mav;
	}
	
	public static void main(String[] args) {
		StringBuffer fileFullPath = new StringBuffer();
    	fileFullPath.append("d://wx")
    				.append("/faUser/cert")
    				.append("/")
    				.append(DateUtil.getDate())
    				.append("/");
    	File dir = new File(fileFullPath.toString());
    	if(!dir.exists()){
    		dir.mkdirs();
    	}
	}
}
